package com.yst.shader.feature.widget

import android.animation.*
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.view.animation.OvershootInterpolator
import com.yst.shader.R
import com.yst.shader.ext.locationInfo
import com.yst.shader.ext.pointOnScreen

/**
 * @author: xuyujian@ysten.com
 *  @date: 2020/8/14 14:55
 */

class FocusView : View {

    private val focus by lazy { BitmapFactory.decodeResource(resources, R.drawable.focus_red) }
    private val statusBarHeight by lazy {
        val id = resources.getIdentifier("status_bar_height", "dimen", "android");
        if (id > 0) {
            resources.getDimensionPixelSize(id)
        } else 0
    }

    private val scaleTo = 1.2f
    private val updateListener by lazy {
        ValueAnimator.AnimatorUpdateListener {
            val scaleFactor = (it.animatedValue as Float)
            println("animate to ${it.animatedValue}")

            scaleX = (scaleTo - 1) * scaleFactor + 1
            scaleY = (scaleTo - 1) * scaleFactor + 1
        }
    }

    private val interpolator by lazy { OvershootInterpolator(1.5f) }
    private val set = AnimatorSet()

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    init {
        addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->

            println("layout : l:$left , t:$top , r:$right , b:$bottom")
            println("layout  W:$width , H:$height")

        }
    }

    private val paint by lazy { Paint() }
    var newFocus: View? = null


    fun focusRoundChange(oldFocus: View?, newFocus: View?) {

//        oldFocus?.scaleX = 1f
//        oldFocus?.scaleY = 1f
//
//        newFocus?.scaleX = scaleTo
//        newFocus?.scaleY = scaleTo
        this.newFocus = newFocus
        newFocus?.let {
            visibility = View.VISIBLE
            newFocus.buildDrawingCache()
            cbm = newFocus.drawingCache
            moveTo(it)
        } ?: kotlin.run {
            visibility = View.INVISIBLE
        }


        oldFocus?.animate()?.scaleX(1f)?.scaleY(1f)
            ?.setInterpolator(interpolator)?.start()

        newFocus?.animate()?.scaleX(scaleTo)?.scaleY(scaleTo)?.setInterpolator(interpolator)
            ?.withStartAction {
                this@FocusView.scaleX = 1f
                this@FocusView.scaleY = 1f
            }?.setUpdateListener(updateListener)?.start()

    }

    var cbm: Bitmap? = null

    private fun moveTo(target: View) {
        println("target location $target")

        if (target.width <= 0) return
        val scaledW = 2f * (target.width - target.paddingLeft - target.paddingRight)
        val scaledH = 2f * (target.height - target.paddingTop - target.paddingBottom)
        val shadowPaddingX = scaledW / 4f
        val shadowPaddingY = scaledH / 4f

        (this.layoutParams as ViewGroup.MarginLayoutParams).also { p ->
            p.width = scaledW.toInt()
            p.height = scaledH.toInt()
            target.locationInfo()
            val array = target.pointOnScreen()
//            p.setMargins(
//                array.component1() - padding.toInt(),
//                array.component2() - statusBarHeight - padding.toInt(),
//                0,
//                0
//            )



            setPadding(5, 5, 5, 5)
            translationX = array.component1() - shadowPaddingX + target.paddingLeft
            translationY =
                array.component2() - statusBarHeight - shadowPaddingY + target.paddingLeft

            requestLayout()
            invalidate()
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (cbm != null) {

            FocusHelper.addFocusShadow(this, canvas, paint, cbm, focus, "")
        }
    }

    fun requestNewFocus() {
        if (newFocus != null) {
            newFocus?.clearAnimation()
            newFocus?.scaleX = 1f
            newFocus?.scaleY = 1f
            newFocus?.post {
                focusRoundChange(null, newFocus)
            }
        }
    }

}